package com.elong.qadev.task;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.elong.qadev.entity.CaseNode;
import com.elong.qadev.entity.Entities;
import com.elong.qadev.entity.Header;
import com.elong.qadev.entity.HttpCase;
import com.elong.qadev.entity.Log_Case;
import com.elong.qadev.entity.Log_TaskInfo;
import com.elong.qadev.entity.NameValuePair;
import com.elong.qadev.entity.RunAfter;
import com.elong.qadev.entity.RunBefore;
import com.elong.qadev.entity.TaskInfo;
import com.elong.qadev.entity.UrlParam;
import com.elong.qadev.entity.WebuiCase;
import com.elong.qadev.model.MailInfo;
import com.elong.qadev.run.RunClient;
import com.elong.qadev.run.RunWebui;
import com.elong.qadev.service.CaseServiceI;
import com.elong.qadev.service.HttpCaseServiceI;
import com.elong.qadev.service.LogServiceI;
import com.elong.qadev.service.TaskServiceI;
import com.elong.qadev.service.WebuiCaseServiceI;
import com.elong.qadev.tool.DateUtils;
import com.elong.qadev.tool.MailUtil;

/**
 * 
 * @ClassName: RunCaseJob
 * @Description: TODO(TASK运行实现类)
 * @author kangchen
 * @date 2015年9月29日
 *
 */
public class RunCaseJob implements Job {
	Logger logger = Logger.getLogger(RunCaseJob.class);
	private TaskServiceI taskService;
	private HttpCaseServiceI httpCaseService;
	private WebuiCaseServiceI webuiCaseService;
	private LogServiceI logService;
	private CaseServiceI caseService;

	@Override
	public void execute(JobExecutionContext context)
			throws JobExecutionException {

		// 初始化运行基础数据
		JobDataMap data = context.getJobDetail().getJobDataMap();
		logger.info("获取TASK处理信息");
		TaskInfo ti = (TaskInfo) data.get("CONTAINS");
		logger.info("生成TASK运行批次号");
		String lastBatchNumber = "";
		try {
			lastBatchNumber = RunCaseJob.genBatchNumber();
		} catch (Exception e) {
			e.printStackTrace();
		}
		ti.setLastBatchNumber(lastBatchNumber);
		logger.info("\n--------------------------------------");
		logger.info("获取到的contains是:" + ti.toString());
		logger.info("开始执行JOB-CLASS:" + this.getClass().getName());
		logger.info("" + context.getJobDetail().getName());
		logger.info("" + context.getJobDetail().getGroup());
		logger.info("" + context.getJobDetail().getJobClass());
		logger.info("--------------------------------------\n");

		// 注入需要的服务类
		logger.info("获取TASK运行服务类");
		ApplicationContext ac = new ClassPathXmlApplicationContext(
				new String[] { "spring.xml", "spring-hibernate.xml" });
		taskService = (TaskServiceI) ac.getBean("taskService");
		logService = (LogServiceI) ac.getBean("logService");
		caseService = (CaseServiceI) ac.getBean("caseService");
		
		logger.info("根据传入taskInfo.contains获取用例数据");
		String[] runCaseId = ti.getContains().split(",");
		Log_TaskInfo logt = new Log_TaskInfo();
		ArrayList<Log_Case> alh = new ArrayList<Log_Case>();

		// 初始化用例计数
		int aborted = 0;
		int passed = 0;
		int failed = 0;
		Date taskStartDate = new Date();

		for (int i = 0; i < runCaseId.length; i++) {
			if (runCaseId[i].equalsIgnoreCase("") || runCaseId[i] == null) {
				continue;
			}

			Log_Case logh = new Log_Case();

			// 获取用例的实际数据
			int caseId = Integer.parseInt(runCaseId[i]);
			CaseNode caseNode = new CaseNode();
			caseNode = caseService.getCase(caseId);
			Date startDate = null;
			Date endDate = null;
			
			//判断是否为HTTP的用例
			if (caseNode.getCaseType().equalsIgnoreCase("HTTP")) {
				// 执行HTTP的用例
				httpCaseService = (HttpCaseServiceI) ac
						.getBean("httpCaseService");
				ArrayList<Header> lh = new ArrayList<Header>();
				ArrayList<UrlParam> lu = new ArrayList<UrlParam>();
				ArrayList<NameValuePair> ln = new ArrayList<NameValuePair>();
				ArrayList<RunBefore> lb = new ArrayList<RunBefore>();
				ArrayList<RunAfter> lr = new ArrayList<RunAfter>();
				Entities entities = new Entities();
				HttpCase httpCase = new HttpCase();
				Map<String, Object> content = new HashMap<String, Object>();

				lh = httpCaseService.getHeaders(caseId);
				lu = httpCaseService.getUrlParams(caseId);
				ln = httpCaseService.getNameValuePairs(caseId);
				lb = httpCaseService.getRunBefores(caseId);
				lr = httpCaseService.getRunAfters(caseId);
				entities = httpCaseService.getEntities(caseId);
				httpCase = httpCaseService.getHttpCase(caseId);

				if (httpCase == null) {
					failed++;
					continue;
				}

				// 整理数据，启动用例执行类
				content.clear();
				content.put("httpCase", httpCase);
				content.put("entities", entities);
				content.put("headers", lh);
				content.put("urlParams", lu);
				content.put("nameValuePairs", ln);
				content.put("runBefores", lb);
				content.put("runAfters", lr);

				RunClient rc = new RunClient(content);
				
				try {
					startDate = new Date();
					rc.run();// 运行用例并得到前后置时间点
					endDate = new Date();
				} catch (Exception e) {
					endDate = new Date();
					aborted++;
					e.printStackTrace();
				} finally {
					logger.info("保存每一个运行的用例执行情况");
					logh.setCaseId(caseId);
					logh.setCaseName(caseNode.getName());
					logh.setCaseType(caseNode.getCaseType());//httpCase.getCaseType()
					logh.setStartDate(startDate);
					logh.setEndDate(endDate);
					logh.setOwer(httpCase.getOwer());
					logh.setExpected(rc.isExpected());
					if (rc.isExpected()) {
						passed++;
					} else {
						failed++;
					}
					logh.setTaskBatchNumber(lastBatchNumber);
					logService.saveLog_h(logh);
					alh.add(logh);
				}
			}else if(caseNode.getCaseType().equalsIgnoreCase("WEBUI")){
				//运行WEBUI的用例
				webuiCaseService=(WebuiCaseServiceI) ac.getBean("webuiCaseService");
				WebuiCase wc = new WebuiCase();
				wc = webuiCaseService.getWebuiCase(caseId);
				if(wc==null){
					failed++;
					continue;
				}
				
				String resultStr = "";
				RunWebui rw = new RunWebui();
				try{
					startDate = new Date();
					resultStr = rw.runReturnResultByTask(wc, resultStr, "chrome-46-WINDOWS");//默认使用谷歌chrome运行		
					endDate = new Date();
				}catch(Exception e){
					endDate = new Date();
					aborted++;
					e.printStackTrace();
				}finally{
					logger.info("保存每一个运行的用例执行情况");
					logh.setCaseId(caseId);
					logh.setCaseName(caseNode.getName());
					logh.setCaseType(caseNode.getCaseType());//httpCase.getCaseType()
					logh.setStartDate(startDate);
					logh.setEndDate(endDate);
					logh.setOwer(wc.getOwner());
					logh.setExpected(rw.isExpected());
					if (rw.isExpected()) {
						passed++;
					} else {
						failed++;
					}
					logh.setTaskBatchNumber(lastBatchNumber);
					logService.saveLog_h(logh);
					alh.add(logh);
				}				
			}
		}
		Date taskEndDate = new Date();

		// 存放TASK运行的记录
		logger.info("保存运行TASK记录");
		logt.setLastBatchNumber(lastBatchNumber);
		logt.setTaskId(ti.getId());
		logt.setTaskName(ti.getTaskName());
		logt.setTotal(runCaseId.length);
		logt.setAborted(aborted);
		logt.setConfiger(ti.getConfiger());
		logt.setStartDate(taskStartDate);
		logt.setEndDate(taskEndDate);
		logt.setPassed(passed);
		logt.setFailed(failed);
		logService.saveLog_t(logt);

		// 生成邮件发送HTML内容
		// alh = logService.getLogHttpCaseByBatchNumber(lastBatchNumber);
		String sendHtml = genHtmlContent(alh, ti, logt);
		logger.info("发送的HTML是：" + sendHtml);

		// 发送生成的HTML内容至TASKINFO中的收件人
		MailInfo mailInfo = null;
		try {
			mailInfo = new MailInfo();
		} catch (Exception e) {
			logger.info("邮件信息初始化失败，请检查配置文件");
			e.printStackTrace();
		}
		mailInfo.setToAddress(ti.getMailTo());
		mailInfo.setSubject("TASK任务-" + ti.getTaskName() + "-("
				+ ti.getLastBatchNumber() + ")");
		logger.info("邮件发送信息是：" + mailInfo.toString());
		mailInfo.setContent(sendHtml);
		try {
			MailUtil.sendHtmlMail(mailInfo);
		} catch (Exception e) {
			logger.info("邮件发送失败，发生异常：" + e.getStackTrace().toString());
		}

		// 更新TASKINFO，展示最后一次运行批次
		taskService.updateTaskInfo(ti);

	}

	/**
	 * @param taskDuration
	 * 
	 * @Title: genHtmlContent
	 * @Description: TODO(邮件发送模板控制)
	 * @param @param alh
	 * @param @param ti
	 * @param @param lt
	 * @param @return 参数
	 * @return String 返回类型
	 * @throws
	 */
	private static String genHtmlContent(ArrayList<Log_Case> alh, TaskInfo ti,
			Log_TaskInfo lt) {
		double tempDuration = lt.getEndDate().getTime()
				- lt.getStartDate().getTime();
		double taskDuration = tempDuration / 1000.0;
		StringBuffer taskResult = new StringBuffer();
		taskResult
				.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">")
				.append("<html>")
				.append("<head>")
				.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">")
				.append("<title>TASK运行结果邮件</title>")
				.append("<style type=\"text/css\">")
				.append(".test{font-family:\"Microsoft Yahei\";font-size: 16px;color: gray;}")
				// margin-right
				.append(".tableMargin{margin-left:20px;width:100%}")
				//
				.append("</style>")
				.append("</head>")
				.append("<body>")
				.append("<div>")
				.append("<span class=\"test\">TASK-ID : task-" + ti.getId()
						+ "<br/>TASK-NAME : " + ti.getTaskName()
						+ "<br/>运行批次 : " + ti.getLastBatchNumber() + "</span>")
				.append("</div>")
				.append("<div><br/></div>")
				.append("<span style=\"font-weight:bold;\">TASK运行结果:</span>")
				.append("<div class=\"tableMargin\">")
				.append("<table border=\"1\" cellspacing=\"0\">")
				.append("<thead>")
				.append("<tr><th>TASK编号</th><th>TASK名称</th><th>总数</th><th>通过</th><th>失败</th><th>异常</th><th>持续时间</th><th>创建者</th></tr>")
				.append("</thead>")
				.append("<tbody>")
				.append("<tr><td>" + lt.getTaskId() + "</td><td>"
						+ lt.getTaskName() + "</td><td>" + lt.getTotal()
						+ "</td><td>" + lt.getPassed()
						+ "</td><td style=\"background-color: red\">"
						+ lt.getFailed() + "</td><td>" + lt.getAborted()
						+ "</td><td>" + taskDuration + "s</td><td>"
						+ lt.getConfiger() + "</td></tr>")
				.append("</tbody>")
				.append("</table>")
				.append("</div>")
				.append("<div><br/></div>")
				.append("<span style=\"font-weight:bold;\">CASE运行结果:</span>")
				.append("<div class=\"tableMargin\">")
				.append("<table border=\"1\" cellspacing=\"0\">")
				.append("<thead>")
				.append("<tr><th>用例编号</th><th>用例名称</th><th>用例类型</th><th>是否通过</th><th>持续时间</th><th>创建者</th></tr>")
				.append("</thead>").append("<tbody>");
		for (int i = 0; i < alh.size(); i++) {
			Log_Case lh = new Log_Case();
			lh = alh.get(i);
			double tempCaseDuration = lh.getEndDate().getTime()
					- lh.getStartDate().getTime();
			double caseDuration = tempCaseDuration / 1000.0;
			if (lh.isExpected())
				taskResult.append("<tr>");
			else
				taskResult.append("<tr style=\"background-color:red\">");
			taskResult.append("<td>" + lh.getCaseId() + "</td>");
			taskResult.append("<td>" + lh.getCaseName() + "</td>");
			taskResult.append("<td>" + lh.getCaseType() + "</td>");
			taskResult.append("<td>" + lh.isExpected() + "</td>");
			taskResult.append("<td>" + caseDuration + " s</td>");
			taskResult.append("<td>" + lh.getOwer() + "</td>");
			taskResult.append("</tr>");
		}
		taskResult.append("</tbody>").append("</table>").append("</div>")
				.append("</body>").append("</html>");
		return taskResult.toString();
	}

	/**
	 * 
	 * @Title: genBatchNumber
	 * @Description: TODO(批次号生成设置)
	 * @param @return
	 * @param @throws Exception 参数
	 * @return String 返回类型
	 * @throws
	 */
	public static String genBatchNumber() throws Exception {
		String str = DateUtils.formatDateIn(new Date());
		String base = "abcdefghijklmnopqrstuvwxyz0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < 5; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		String value = sb.toString();
		long seconds = System.currentTimeMillis();
		str += "-" + seconds + value;
		return str;
	}

	public static void main(String[] args) throws Exception {
		for (int i = 0; i < 50; i++) {
			System.out.println(RunCaseJob.genBatchNumber());
		}
	}
}
